#include <physicsManager2d.h>
#include <mesh2d.h>

#include "windowStuff.h"

using namespace ePhys;

class shape {
public:
	obj2d *pos, *vel;
};

physicsManager2d physics;
shape shape1, shape2;
HPEN black, grey;

bool rotating;
vec2d mouseStart;
obj2d *moving = NULL;

void makeColors(void) {
	black = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
	grey = CreatePen(PS_SOLID, 2, RGB(128, 128, 128));
}

void makeShapes(void) {
	//Mesh loader helps to load your collision mesh's into the engine
	meshLoader2d mloader;

	//Construct a triangle
	tri2d simpleTri = tri2d(
		vec2d(0.f, 50.f),
		vec2d(-50.f, -50.f),
		vec2d(50.f, -50.f));

	//Add triangles one by one to make a mesh
	mloader.addTriangle(simpleTri);

	//The loader will build the finished mesh for you
	shape1.pos = mloader.finish();

	//Set a position in the world
	shape1.pos->setPosition(vec2d(200.0f,200.0f));

	//Add to the physics manager
	physics.addObject(shape1.pos);
	
	//Add another object to manipulate velocity
	mloader.addTriangle(simpleTri);
	shape1.vel = mloader.finish();
	shape1.vel->setPosition(vec2d(400.0f,200.f));
	shape1.vel->setStatic(true);
	physics.addObject(shape1.vel);

	//Second shape
	mloader.addTriangle(simpleTri);
	shape2.pos = mloader.finish();
	shape2.pos->setPosition(vec2d(200.0f,400.f));
	shape2.pos->setStatic(true);
	physics.addObject(shape2.pos);

	mloader.addTriangle(simpleTri);
	shape2.vel = mloader.finish();
	shape2.vel->setPosition(vec2d(400.0f,400.f));
	shape2.vel->setStatic(true);
	physics.addObject(shape2.vel);
}


//Startup function
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE h2, LPSTR 
	d3, int nCmdShow) {

	//Set the colours
	makeColors();

	//make the shapes
	makeShapes();

	//Make the window to display the results in
	makeWindow(hInst); 

	//Clean up
	physics.drop(); 
	//Any objects you add to the physics manager will be delete for you
	//So need need to delete shape1 and shape2

	//Exit program
	return 0;
}

//Draw a triangle
void drawTri(HDC hDC, tri2d *t, vec2d &pos, HPEN color) {
	SelectObject(hDC, color);

	MoveToEx(hDC, (int) (t->p1.x+pos.x), (int) (t->p1.y+pos.y), NULL);
	LineTo(hDC, (int) (t->p2.x+pos.x), (int) (t->p2.y+pos.y));
	LineTo(hDC, (int) (t->p3.x+pos.x), (int) (t->p3.y+pos.y));
	LineTo(hDC, (int) (t->p1.x+pos.x), (int) (t->p1.y+pos.y));
}

//Draw an object
void drawObject(HDC hDC, obj2d *o, HPEN color) {

	//Check which shape it is
	switch(o->type()) {

		//Draw a mesh
	case OBJ_MESH2D:
		mesh2d *m = (mesh2d*) o;
		tri2d *t = m->getBuffer();
		for(u32 i = 0; i < m->getBufferSize(); i++) 
			drawTri(hDC, &t[i], o->getPosition(), color);
	}
}

//Draw a shape
void drawShape(HDC hDC, shape *s) {
	//Draw direction of movement
	SelectObject(hDC, grey);
	MoveToEx(hDC, (int) (s->pos->getPosition().x+s->pos->center.x), 
		(int) (s->pos->getPosition().y+s->pos->center.y), NULL);
	LineTo(hDC, (int) (s->vel->getPosition().x+s->vel->center.x), 
		(int) (s->vel->getPosition().y+s->vel->center.y));

	//Draw shape bounds
	drawObject(hDC, s->pos, black);
	drawObject(hDC, s->vel, grey);
}

void draw(HDC hDC) {
	drawShape(hDC, &shape1);	
	drawShape(hDC, &shape2);	
}

void mouseDown(bool left, int mx, int my) {
	if(moving) 
		moving = NULL;
	else {
		moving = physics.pick(vec2d(mx, my));
		mouseStart = vec2d(mx, my);
		rotating = (left==false);
	}
}

void mouseMove(int mx, int my, HWND hWnd) {
	if(moving && !rotating) {		
		vec2d oldPos = moving->getPosition();
		vec2d mouseNew(mx,my);
		vec2d mouseDelta = mouseNew - mouseStart;
		moving->setPosition(oldPos + mouseDelta);
		mouseStart = mouseNew;
		InvalidateRect(hWnd, NULL, true); //redraw the screen
	}
}

void mouseUp() {
	
}